<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class CreateProjectCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'project:controller {project_name} {controller_name=index}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '创建API集群项目控制器: project:controller 项目名 控制器名(可选,默认为 Index)';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    protected function getStub()
    {
        return __DIR__ . '/stubs/project/controller.stub';
    }

    protected function getDefaultNamespace($rootNamespace)
    {
        return $rootNamespace . '\Controllers';
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $args = $this->arguments();

        // NameSpaceExplode
        $namespaceExplode = explode('/', str_replace(['/', '//'], '/', $args['controller_name']));
        $fileExplode      = null;
        if (count($namespaceExplode) > 1) {
            $class_name = ucfirst(array_pop($namespaceExplode)) . 'Controller';
            foreach ($namespaceExplode as $k => $v) {
                $namespaceExplode[$k] = ucfirst($v);
            }
            $namespace = 'Project\\' . ucfirst($args['project_name']) . '\\Controllers\\' . join('\\', $namespaceExplode);
            $fileExplode = join('/', $namespaceExplode) . '/';
        } else {
            // NameSpace
            $namespace = 'Project\\' . ucfirst($args['project_name']) . '\\Controllers';
            // Class name
            $class_name = ucfirst($args['controller_name']) . 'Controller';
        }

        // File name
        $file_name = ucfirst($class_name . '.php');

        // File path
        $logic_file = app_path() .
            '/Project/' .
            ucfirst($args['project_name']) .
            '/Controllers/' .
            $fileExplode .
            $file_name;

        // File dir
        $logic_path = dirname($logic_file);

        // 首次创建项目
        if (!is_dir(app_path('project/' . ucfirst($args['project_name']) . '/Controllers'))) {
            @mkdir(app_path('project/' . ucfirst($args['project_name'])), 0755, true);
            @mkdir(app_path('project/' . ucfirst($args['project_name']) . '/Controllers'), 0755, true);
            @mkdir(app_path('project/' . ucfirst($args['project_name']) . '/Middleware'), 0755, true);
            @mkdir(app_path('project/' . ucfirst($args['project_name']) . '/Routes'), 0755, true);
            // 路由创建
            $route = file_get_contents(dirname(__FILE__) . '/stubs/project/routes.stub');
            $source = str_replace(['[project]', '[namespace]', '[controller]'], [strtolower($args['project_name'] . ($fileExplode ? '/' . trim($fileExplode, '/') : null)), $namespace, $class_name], $route);

            if (!file_put_contents(app_path() . '/Project/' . ucfirst($args['project_name']) . '/Routes/api.php', $source)) {
                $this->error('路由创建失败！');
                exit;
            }
        }

        // 特殊的 NameSpace 使用特殊的 Extends 文件
        $baseExtends = [
            'admin' => 'Project\Admin\Controllers\BaseController'
        ];
        if (in_array(strtolower($args['project_name']), array_keys($baseExtends))) {
            $extends = $baseExtends[strtolower($args['project_name'])];
        } else {
            $extends = 'App\Http\Controllers\Controller as BaseController';
        }

        //获取模板,替换变量
        $template = file_get_contents(dirname(__FILE__) . '/stubs/project/controller.stub');
        $default_method = file_get_contents(dirname(__FILE__) . '/stubs/project/defaultMethod.stub');
        $default_method = $this->replaceMethod($default_method, $args);
        $source = str_replace('[api_base]', ucfirst($args['project_name']), $template);
        $source = str_replace('[namespace]', $namespace, $source);
        $source = str_replace('[class_name]', $class_name, $source);
        $source = str_replace('[base_extends]', $extends, $source);
        $source = str_replace('[default_method]', $default_method, $source);

        //是否已存在相同文件
        if (file_exists($logic_file)) {
            $this->error('文件已存在');
            exit;
        }

        //创建
        if (file_exists($logic_path) === false) {
            if (mkdir($logic_path, 0755, true) === false) {
                $this->error('目录 <' . $logic_path . '> 没有写入权限');
                exit;
            }
        }

        //写入
        if (!file_put_contents($logic_file, $source)) {
            $this->error('创建失败！');
            exit;
        }

        $this->info('创建成功！');
    }

    protected function replaceMethod($str, $args)
    {
        $cnt = last(explode('\\', str_replace(['\\', '\\\\'], '\\', $args['controller_name'])));
        $cnt = (!$cnt || $cnt === strtolower('index')) ? '' : '/' . strtolower($cnt);
        return str_replace([
            '{api_index_router}',
            '{api_show_router}',
            '{api_update_router}',
            '{api_edit_router}',
            '{api_store_router}',
            '{api_create_router}',
            '{api_destroy_router}',
            '{api_group}'
        ], [
            '/api/' . strtolower($args['project_name']) . $cnt,
            '/api/' . strtolower($args['project_name']) . $cnt . '/{id}',
            '/api/' . strtolower($args['project_name']) . $cnt . '/{id}',
            '/api/' . strtolower($args['project_name']) . $cnt . '/{id}',
            '/api/' . strtolower($args['project_name']) . $cnt,
            '/api/' . strtolower($args['project_name']) . $cnt,
            '/api/' . strtolower($args['project_name']) . $cnt . '/{id}',
            ucfirst($args['project_name']) . ($cnt ? '/' . ucfirst(trim($cnt, '/')) : '')
        ], $str);
    }
}
